//
//  WBStatusListViewModel.swift
//  仿微博
//
//  Created by apple on 2016/12/21.
//  Copyright © 2016年 apple. All rights reserved.
//

import Foundation
import SDWebImage
/// 微博数据列表视图模型
/*
 
 父类的选择
 - 如果类需要使用 ‘KVC’ 或者字典转模型框架设置对象值 ，类就需要继承  NSObject
 - 如果类只是包装一些代码逻辑（写了一些函数）， 可以不用任何父类 ，好处： 更加轻量级
 - 提示：如果用  OC 写， 一律都继承自 NSObject 即可
 
 
 使命： 负责微博的数据处理
 1.字典转模型
 2.下拉/上拉刷新 数据处理
 
 */
///上拉刷新最大尝试次数

 private let maxPullupTryTimes = 3

class WBStatusListViewModel {
    
    
    /// 微博视图模型数据懒加载
    lazy var statusList = [WBStatusViewModel]()
    ///上次刷新错误次数
    private var PullupErrorTimes = 0
    /// 加载微博列表
    ///
    ///   - pullup: 是否上拉刷新标记
    /// - Parameter completion: 完成回调【网络请求是否成功, 是否刷新表格】
    
    func loadStatus(pullup: Bool, completion: @escaping (_ isSuccess: Bool, _ shouldRefresh: Bool)->()) {
        
        //判断是否是上拉刷新个，同是检查刷新错误
        if pullup && PullupErrorTimes > maxPullupTryTimes{
        
        completion(true, false)
        return
        
        }
        
        
        
       // since_id 取出数组中第一条微博的 id
        let since_id = pullup ? 0 : statusList.first?.status.id ?? 0
        //上拉刷新,取出数组的最后一条微博的 id
        let max_id = !pullup ? 0 : statusList.last?.status.id ?? 0
        
    WBNetworkManager.shared().statusList(since_id: since_id, max_id: max_id) { (list, isSuccess) in
        
        //0.判断网络请求是否成功
        if !isSuccess {
        //直接回调返回
            completion(false, false)
        
        return
        
        }
        
        
        
        //1.遍历  服务器返回的数组 ，字典转 模型 => 视图模型
       
        var array = [WBStatusViewModel]()
      
        for dict in list ?? [] {
//        print(dict["pic_urls"])
            //1>创建微博模型
            let status = WBStatus()
            //2>使用字典设置设置模型
            status.yy_modelSet(with: dict)
            //3>使用 “微博” 模型创建 ‘微博视图模型’
            let viewModel = WBStatusViewModel(model: status)
            //4.>添加到数组
            array.append(viewModel)
            
            }
        //视图模型创建完成
        print("刷新到 \(array.count) 条微博\(array)")
        //2.  拼接数据
        if pullup {
            //上拉刷新，应该将结果数组拼接在数组末尾
            self.statusList += array
        }else{
            //下拉刷新，应该将结果数组拼接在数组前面
            self.statusList = array + self.statusList
        }
        // 判断上拉刷新的数量
        if pullup && array.count == 0 {
        self.PullupErrorTimes += 1
            completion(isSuccess, false)
        }else{
            self.cacheSingleImage(list: array, finished: completion)
            //3.真正有数据的回调
            //completion(isSuccess, true)
        }
        
    }
 
    }
    
    /// 缓存本次下载微博数据数组中单张图片
    ///
    /// - 应该缓存完单张图像，并且修改过配图的大小之后， 再回调，才能够保证表格等比例显示单张图像
    
    ///
    /// - Parameter list: 本次下载的视图模型数组
    private func cacheSingleImage(list: [WBStatusViewModel],finished: @escaping (_ isSuccess: Bool, _ shouldRefresh: Bool)->()) {
        //调度组
        let group = DispatchGroup()
      //记录数据长度
        var lenght = 0
      // 遍历数组 ，  查找微博中有单张图像的， 进行缓存
        
        for vm in list {
            //1. 判断图像数量
            if vm.picURLs?.count != 1 {
                continue
            }
            //2.代码执行到此， 数组中有且仅有一张图片
            guard let pic = vm.picURLs?[0].thumbnail_pic,
                let url = URL(string: pic)
               else {
                continue
            }
//            print("要缓存的  URL \(url)" )
            //3.下载图像
            //1)downloadImage是SDWebImage 的核心方法
            //2)图像下载完成后，会自动保存在沙盒中，文件路径是URL 的MD5
            //3)如果沙盒中已经存在缓存的图像，后续使用 SD 通过 URL 加载图像， 都会加载本地沙盒的图像
            //4)不会发起网路请求，同时回调方法，同样会调用
            //5)方法还是同样的方法，调用还是同样的调用，不过内部不会发起网络请求
            // ***
            
            
            // A> 入组
            group.enter()
            
            SDWebImageManager.shared().downloadImage(with: url, options: [], progress: nil, completed: { (image, _, _, _, _) in
                //将图像转成二进制
                if let image = image,
                    let data = UIImagePNGRepresentation(image){
                    // NSData 是lenght的属性
                  lenght += data.count
                    //图像缓存成功，更新配图视图的大小
                    vm.updateSingImageSize(image: image)
                }
                
                print("缓存的图像是\(image) 长度 \(lenght)")
                //B>出组  --放在回调的最后一句
                group.leave()
            })
        }
//    监听调度组情况
        group.notify(queue: DispatchQueue.main) { 
            print("图像缓存完成 \(lenght / 1024)K")
            //执行闭包回调
            finished(true, true)
            
        }
    
    
    }
}
